home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / p_aa4re / bb212src / bbmf3.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-03-07  |  22.4 KB  |  522 lines

  1. (*===========================================================================*)
  2. (* Find/Search                                                               *)
  3. (*                                                                           *)
  4. (*   Copyright 1988, 1989, 1990, 1991, 1992 by H. Roy Engehausen.  All       *)
  5. (*   rights reserved.                                                        *)
  6. (*                                                                           *)
  7. (*===========================================================================*)
  8.  
  9. (*===========================================================================*)
  10. (* Search for a msg                                                          *)
  11. (*      Types of searches:                                                   *)
  12. (*           ' ' = By number                                                 *)
  13. (*           '#' = By number (but no termination)                            *)
  14. (*           'C' = User class                                                *)
  15. (*           'D' = By date                                                   *)
  16. (*           'E' = Find to a user at this BBS (For servers)                  *)
  17. (*           'G' = Currently logged on station                               *)
  18. (*           'K' = By flag and number                                        *)
  19. (*           'L' = Find last "n" msgs                                        *)
  20. (*           'M' = find all messages either to or from user                  *)
  21. (*           'O' = find all messages at a user - Check to field only.        *)
  22. (*                            Must be forwardable and have no H address      *)
  23. (*           'Q' = find all read messages to user                            *)
  24. (*           'R' = find all unread messages to user                          *)
  25. (*           'S' = find all messages with matching pattern in Subj           *)
  26. (*           'T' = find all messages of a certain type                       *)
  27. (*           '$' = find all messages with matching pattern in BID            *)
  28. (*           '<' = find all messages from a user                             *)
  29. (*           '>' = find all messages to a user                               *)
  30. (*           '@' = find all messages to a bbs                                *)
  31. (*           '%' = find all messages from a bbs                              *)
  32. (*                                                                           *)
  33. (* WARNING !!!!  Indentation rules not fully followed to improve code        *)
  34. (* size and execution speed                                                  *)
  35. (*                                                                           *)
  36. (*===========================================================================*)
  37.  
  38. PROCEDURE search_msg(search : search_block_ptr);
  39.  
  40.   {$UNDEF  DEBUG3A}
  41.   {$UNDEF  DEBUG3B}
  42.   {$UNDEF  DEBUG3C} (* Used to debug intermittent actions *)
  43.   {$UNDEF  DEBUG3D} (* Debug back search block            *)
  44.  
  45.   VAR
  46.     ascend               : BOOLEAN;
  47.     b                    : BOOLEAN;
  48.     found                : BOOLEAN;
  49.     do_hide_check        : BOOLEAN;
  50.     i                    : BYTE;
  51.     msg_index_current    : msg_index_ptr;
  52.     nok_switch           : BOOLEAN;
  53.     our_search           : search_block_type;
  54.     save_last            : msg_index_ptr;
  55.     this_search_block    : search_block_ptr;
  56.  
  57.   BEGIN;
  58.  
  59.     (*-----------------------------------------------------------------------*)
  60.     (* Initialize                                                            *)
  61.     (*-----------------------------------------------------------------------*)
  62.  
  63.     this_search_block := search;
  64.  
  65.     (*-----------------------------------------------------------------------*)
  66.     (* Set main no kill switch and directions                                *)
  67.     (*-----------------------------------------------------------------------*)
  68.  
  69.     nok_switch        := TRUE;
  70.     ascend            := FALSE;
  71.  
  72.     {$IFDEF POINT_CHK}
  73.       test_pointer(this_search_block);
  74.     {$ENDIF}
  75.  
  76.     REPEAT
  77.  
  78.       {$IFDEF POINT_CHK}
  79.         test_pointer(this_search_block);
  80.       {$ENDIF}
  81.  
  82.       ascend            := ascend     OR  this_search_block^.search_ascend;
  83.       nok_switch        := nok_switch AND this_search_block^.search_nok;
  84.       this_search_block := this_search_block^.search_next;
  85.  
  86.     UNTIL (this_search_block = NIL) OR NOT nok_switch;
  87.  
  88.     (*-----------------------------------------------------------------------*)
  89.     (* More initialization                                                   *)
  90.     (*-----------------------------------------------------------------------*)
  91.  
  92.     our_search        := search^;
  93.     this_search_block := search;
  94.  
  95.     (*-----------------------------------------------------------------------*)
  96.     (* Debugging                                                             *)
  97.     (*-----------------------------------------------------------------------*)
  98.  
  99.     {$IFDEF DEBUG3A}
  100.       REPEAT
  101.         WRITELN('Type   = ', this_search_block^.search_type);
  102.         WRITELN('Ascend = ', this_search_block^.search_ascend);
  103.         WRITELN('Above  = ', this_search_block^.search_above);
  104.         WRITELN('NOK    = ', this_search_block^.search_nok);
  105.         WRITELN('Msg_No = ', this_search_block^.search_msg_no);
  106.         DELAY(1000);
  107.         this_search_block := this_search_block^.search_next;
  108.       UNTIL this_search_block = NIL;
  109.       this_search_block := search;
  110.     {$ENDIF}
  111.  
  112.     (*-----------------------------------------------------------------------*)
  113.     (* Debugging                                                             *)
  114.     (*-----------------------------------------------------------------------*)
  115.  
  116.     {$IFDEF DEBUG3B}
  117.        trace_data('M31', this_search_block^.search_msg_no,
  118.                          our_search.search_last,
  119.                          '');
  120.     {$ENDIF}
  121.  
  122.     {$IFDEF DEBUG3C}
  123.        trace_data('MF3 1', ORD(our_search.search_type),
  124.                          our_search.search_last,
  125.                          '');
  126.     {$ENDIF}
  127.  
  128.     (*-----------------------------------------------------------------------*)
  129.     (* Initialize for the search loop.  The start of the search should       *)
  130.     (* be the next msg from our last hit.  If this is the start of a         *)
  131.     (* search then use one of the ends of the chain.  Note that there        *)
  132.     (* are two chains: the main chain of all messages and the "n_list"       *)
  133.     (* chain.  The latter contains messages that may be awaiting forward.    *)
  134.     (* This chain is a lot shorter and speeds up forwarding                  *)
  135.     (*-----------------------------------------------------------------------*)
  136.  
  137.     IF our_search.search_last <> NIL THEN
  138.       BEGIN;
  139.  
  140.         {$IFDEF POINT_CHK}
  141.           test_pointer(our_search.search_last);
  142.         {$ENDIF}
  143.  
  144.         IF NOT our_search.search_one_only THEN
  145.           BEGIN;
  146.             IF ascend THEN
  147.               msg_index_current := our_search.search_last^.msg_i_next
  148.             ELSE
  149.               msg_index_current := our_search.search_last^.msg_i_last;
  150.           END
  151.         ELSE
  152.           msg_index_current := our_search.search_last;
  153.       END
  154.     ELSE
  155.       BEGIN;
  156.         IF ascend THEN
  157.           msg_index_current := msg_index_start
  158.         ELSE
  159.           msg_index_current := msg_index_end;
  160.       END;
  161.  
  162.     (*-----------------------------------------------------------------------*)
  163.     (* Debugging                                                             *)
  164.     (*-----------------------------------------------------------------------*)
  165.  
  166.     {$IFDEF DEBUG3B}
  167.        trace_data('M32', this_search_block^.search_msg_no,
  168.                          our_search.search_last,
  169.                          '');
  170.     {$ENDIF}
  171.  
  172.     {$IFDEF DEBUG3C}
  173.        trace_data('MF3 2', ORD(our_search.search_type),
  174.                          our_search.search_last,
  175.                          '');
  176.     {$ENDIF}
  177.  
  178.     (*-----------------------------------------------------------------------*)
  179.     (* Set our switches off and prep the save pointer.                       *)
  180.     (*-----------------------------------------------------------------------*)
  181.  
  182.     found     := FALSE;
  183.     save_last := our_search.search_last;
  184.  
  185.     do_hide_check := NOT our_search.search_one_only;
  186.  
  187.     (*-----------------------------------------------------------------------*)
  188.     (* This loop is the search loop                                          *)
  189.     (*-----------------------------------------------------------------------*)
  190.  
  191.     WHILE (NOT found) AND (msg_index_current <> NIL) DO
  192.       BEGIN;
  193.  
  194.         (*------------------------------------------------------------------*)
  195.         (* If we were not at the top of the chain, set us back to the top   *)
  196.         (*------------------------------------------------------------------*)
  197.  
  198.         IF this_search_block <> search THEN
  199.           BEGIN;
  200.             this_search_block := search;
  201.             our_search        := search^;
  202.           END;
  203.  
  204.         REPEAT
  205.  
  206. (*---------------------------------------------------------------------------*)
  207. (* Indentation VIOLATION starts here                                         *)
  208. (*---------------------------------------------------------------------------*)
  209.  
  210. (*---------------------------------------------------------------------------*)
  211. (* See if current message meets criteria                                     *)
  212. (*---------------------------------------------------------------------------*)
  213.  
  214. CASE our_search.search_type OF
  215.  
  216.   (*-------------------------------------------------------------------------*)
  217.   (* '<' = find all messages from a user                                     *)
  218.   (* '>' = find all messages to a user                                       *)
  219.   (* '@' = find all messages to a BBS                                        *)
  220.   (* '@' = find all messages from a BBS                                      *)
  221.   (* 'E' = Find to a user at this BBS (For servers)                          *)
  222.   (* 'S' = find all messages with matching string in subj                    *)
  223.   (* '$' = find all messages with matching string in bid                     *)
  224.   (* '.' = find all messages with matching string in hier address            *)
  225.   (*-------------------------------------------------------------------------*)
  226.  
  227.    '@' : found := match_str(msg_index_current^.msg_i_mb.msg_to_at,
  228.                       our_search.search_str);
  229.    '>' : found := match_str(msg_index_current^.msg_i_mb.msg_to,
  230.                       our_search.search_str);
  231.    '<' : found := match_str(msg_index_current^.msg_i_mb.msg_from,
  232.                       our_search.search_str);
  233.    '.' : found := match_str(msg_index_current^.msg_i_mb.msg_to_h,
  234.                       our_search.search_str);
  235.    '$' : found := match_str(msg_index_current^.msg_i_mb.msg_bid,
  236.                       our_search.search_str);
  237.    '%' : found := match_str(msg_index_current^.msg_i_mb.msg_from_at,
  238.                       our_search.search_str);
  239.    'E' : found := match_str(msg_index_current^.msg_i_mb.msg_to,
  240.                             our_search.search_str)
  241.          AND ((msg_index_current^.msg_i_mb.msg_to_at = '')
  242.                          OR (msg_index_current^.msg_i_mb.msg_to_at =
  243.                                                     opt_block.this_bb_sign));
  244.    'S' : found := match_str(upcase_str(msg_index_current^.msg_i_mb.msg_subj),
  245.                       our_search.search_str);
  246.  
  247.   (*-------------------------------------------------------------------------*)
  248.   (* ' ' = search by number (either above or below a value)                  *)
  249.   (* '#' = search by number (either above or below a value)                  *)
  250.   (*-------------------------------------------------------------------------*)
  251.  
  252.   ' ', '#' : BEGIN;
  253.  
  254.          IF our_search.search_above THEN
  255.            found :=
  256.              (msg_index_current^.msg_i_mb.msg_number >=
  257.                                                      our_search.search_msg_no)
  258.          ELSE
  259.            found :=
  260.              (msg_index_current^.msg_i_mb.msg_number <=
  261.                                                      our_search.search_msg_no);
  262.  
  263.        END; (*----- End search ' ' ------------------------------------------*)
  264.  
  265.   (*-------------------------------------------------------------------------*)
  266.   (* 'D' = Show messages older/newer than a certain date/time                *)
  267.   (*-------------------------------------------------------------------------*)
  268.  
  269.   'D': BEGIN;
  270.  
  271.          IF our_search.search_above THEN
  272.            found := msg_index_current^.msg_i_mb.msg_dt_in
  273.                                                        >= our_search.search_dt
  274.          ELSE
  275.            found := msg_index_current^.msg_i_mb.msg_dt_in
  276.                                                        <= our_search.search_dt;
  277.  
  278.        END; (*----- End search 'D' ------------------------------------------*)
  279.  
  280.   (*-------------------------------------------------------------------------*)
  281.   (* 'K' = find message by number and does contain a flag                    *)
  282.   (* 'N' = find message by number and does not contain a flag                *)
  283.   (*-------------------------------------------------------------------------*)
  284.  
  285.   'K', 'N': BEGIN;
  286.  
  287.          IF our_search.search_above THEN
  288.            found := (msg_index_current^.msg_i_mb.msg_number
  289.                                                   >= our_search.search_msg_no)
  290.          ELSE
  291.            found := (msg_index_current^.msg_i_mb.msg_number
  292.                                                   <= our_search.search_msg_no);
  293.  
  294.          IF found THEN
  295.            BEGIN;
  296.              found := (msg_index_current^.msg_i_mb.msg_flag
  297.                                                 AND our_search.search_mf) <> 0;
  298.              IF our_search.search_type = 'N' THEN
  299.                found := NOT found;
  300.            END;
  301.  
  302.        END;
  303.  
  304.   (*-------------------------------------------------------------------------*)
  305.   (* 'L' = Find last "n" msgs                                                *)
  306.   (*-------------------------------------------------------------------------*)
  307.  
  308.   'L': BEGIN;
  309.  
  310.          found := our_search.search_msg_no <> 0;
  311.  
  312.          IF found THEN
  313.            found := check_hidden(msg_index_current);
  314.  
  315.          IF found THEN
  316.            this_search_block^.search_msg_no := our_search.search_msg_no - 1;
  317.  
  318.          do_hide_check := FALSE;
  319.  
  320.        END; (*----- End search "L" ------------------------------------------*)
  321.  
  322.   (*-------------------------------------------------------------------------*)
  323.   (* 'M' = find all messages belonging to a user                             *)
  324.   (*-------------------------------------------------------------------------*)
  325.  
  326.   'M': BEGIN;
  327.  
  328.          found := (msg_index_current^.msg_i_mb.msg_to = our_search.search_str)
  329.                   OR (msg_index_current^.msg_i_mb.msg_from
  330.                                                       = our_search.search_str)
  331.                   OR (msg_index_current^.msg_i_mb.msg_to_at
  332.                                                       = our_search.search_str)
  333.                   OR (msg_index_current^.msg_i_mb.msg_from_at
  334.                                                       = our_search.search_str);
  335.  
  336.        END;
  337.  
  338.   (*-------------------------------------------------------------------------*)
  339.   (* 'Q' = find all   read messages to user                                  *)
  340.   (* 'R' = find all unread messages to user                                  *)
  341.   (*-------------------------------------------------------------------------*)
  342.  
  343.   'Q', 'R': BEGIN;
  344.  
  345.          found := match_str(msg_index_current^.msg_i_mb.msg_to,
  346.                                                         our_search.search_str);
  347.  
  348.          IF found THEN
  349.            BEGIN;
  350.              IF our_search.search_type = 'Q' THEN
  351.                found := (msg_index_current^.msg_i_mb.msg_flag
  352.                                                        AND mf_read) <> 0
  353.              ELSE
  354.                found := (msg_index_current^.msg_i_mb.msg_flag
  355.                                                        AND not_read_flags) = 0;
  356.            END;
  357.  
  358.        END;
  359.  
  360.   (*-------------------------------------------------------------------------*)
  361.   (* 'T' = find all messages of a certain type                               *)
  362.   (*-------------------------------------------------------------------------*)
  363.  
  364.   'T': BEGIN;
  365.  
  366.          found := msg_index_current^.msg_i_mb.msg_type
  367.                                                     = our_search.search_str[1];
  368.  
  369.        END;
  370.  
  371.   (*-------------------------------------------------------------------------*)
  372.   (* 'C' = Checks the current user class.  This is really here for action    *)
  373.   (* file stuff.  The result is not based on the message                     *)
  374.   (*-------------------------------------------------------------------------*)
  375.  
  376.   'C': BEGIN;
  377.  
  378.          found := active_tcb^.uid_data.user_class
  379.                                                <= our_search.search_user_class;
  380.  
  381.        END;
  382.  
  383.   (*-------------------------------------------------------------------------*)
  384.   (* 'G' = Checks the current logged on user.  This is here for action       *)
  385.   (* file stuff.  The result is not based on the message                     *)
  386.   (*-------------------------------------------------------------------------*)
  387.  
  388.   'G': BEGIN;
  389.  
  390.          found := active_tcb^.uid_data.user_id = our_search.search_str;
  391.  
  392.        END;
  393.  
  394.  
  395.   (*-------------------------------------------------------------------------*)
  396.   (* Catch bugs                                                              *)
  397.   (*-------------------------------------------------------------------------*)
  398.  
  399.   ELSE
  400.     BEGIN;
  401.       WRITELN;
  402.       WRITELN('Search error -- ', our_search.search_type,
  403.                           ' -- ', ORD(our_search.search_type));
  404.       WRITELN;
  405.       RUNERROR(msg_runerr);
  406.     END;
  407.  
  408. END; (*----- End search case statement --------------------------------------*)
  409.  
  410. (*---------------------------------------------------------------------------*)
  411. (* Invert as needed                                                          *)
  412. (*---------------------------------------------------------------------------*)
  413.  
  414. {$IFDEF DEBUG3D}
  415.   IF BYTE(our_search.search_invert) > 1 THEN
  416.     BEGIN;
  417.       dump_reason('Bad search arg....');
  418.       dump_state;
  419.       dump_trace;
  420.       dump_action_all;
  421.       dump_search_chain(search);
  422.       dump_hex_addr(@our_search, LENGTH(our_search));
  423.       RUNERROR(msg_runerr);
  424.     END;
  425.  
  426.   IF BYTE(found) > 1 THEN
  427.     BEGIN;
  428.       dump_reason('Bad state of found switch');
  429.       dump_hex_addr(@found, 1));
  430.       dump_state;
  431.       dump_trace;
  432.       RUNERROR(msg_runerr);
  433.     END;
  434.  
  435. {$ENDIF}
  436.  
  437.  
  438. found := our_search.search_invert XOR found;
  439.  
  440. (*---------------------------------------------------------------------------*)
  441. (* For special conditions, make sure we don't find a killed message when we  *)
  442. (* didn't want one                                                           *)
  443. (*---------------------------------------------------------------------------*)
  444.  
  445. IF found AND nok_switch
  446.              AND ((msg_index_current^.msg_i_mb.msg_flag AND mf_kill) <> 0) THEN
  447.   found := FALSE;
  448.  
  449. (*---------------------------------------------------------------------------*)
  450. (* Indentation VIOLATION ends here                                           *)
  451. (*---------------------------------------------------------------------------*)
  452.  
  453.           (*-----------------------------------------------------------------*)
  454.           (* We should loop again to AND a search condition                  *)
  455.           (*-----------------------------------------------------------------*)
  456.  
  457.           b := found AND (our_search.search_next <> NIL);
  458.  
  459.           (*-----------------------------------------------------------------*)
  460.           (* If so then chain to the next search                             *)
  461.           (*-----------------------------------------------------------------*)
  462.  
  463.           IF b THEN
  464.             BEGIN;
  465.               this_search_block := our_search.search_next;
  466.               our_search        := this_search_block^;
  467.             END;
  468.  
  469.           (*-----------------------------------------------------------------*)
  470.           (* Loop until a search fails or we run out of searches             *)
  471.           (*-----------------------------------------------------------------*)
  472.  
  473.         UNTIL NOT b;
  474.  
  475.         (*-------------------------------------------------------------------*)
  476.         (* Switch back to main search block                                  *)
  477.         (*-------------------------------------------------------------------*)
  478.  
  479.         IF this_search_block <> search THEN
  480.           BEGIN;
  481.             this_search_block := search;
  482.             our_search        := search^;
  483.           END;
  484.  
  485.         (*-------------------------------------------------------------------*)
  486.         (* See if message should be hidden from user                         *)
  487.         (*-------------------------------------------------------------------*)
  488.  
  489.         IF found AND do_hide_check THEN
  490.           found := check_hidden(msg_index_current);
  491.  
  492.         (*-------------------------------------------------------------------*)
  493.         (* If we didn't find the right one and there are more to search      *)
  494.         (* then point to the next message to be tested                       *)
  495.         (*-------------------------------------------------------------------*)
  496.  
  497.         IF (NOT found) AND (msg_index_current <> NIL) THEN
  498.           BEGIN;
  499.             IF our_search.search_one_only THEN
  500.               msg_index_current := NIL
  501.             ELSE
  502.               IF ascend THEN
  503.                 msg_index_current := msg_index_current^.msg_i_next
  504.               ELSE
  505.                 msg_index_current := msg_index_current^.msg_i_last;
  506.           END;
  507.  
  508.       END; (*----- End search loop ------------------------------------------*)
  509.  
  510.     (*-----------------------------------------------------------------------*)
  511.     (* Set the search results                                                *)
  512.     (*-----------------------------------------------------------------------*)
  513.  
  514.     IF found THEN
  515.       search^.search_last := msg_index_current
  516.     ELSE
  517.       search^.search_last := NIL;
  518.  
  519.     search^.search_fi := our_search.search_fi;
  520.  
  521.   END;
  522.